package com.android.lovely.framework

import android.annotation.SuppressLint
import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.paging.LoadState
import androidx.paging.LoadStateAdapter
import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.ConcatAdapter
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.android.lovely.databinding.AdapterLoadingFooterBinding
import com.kotlin.extensions.inflater.LayoutInflaterExt.layoutInflater
import com.kotlin.extensions.view.ViewExt.clickable

/**
 *
 * @author why
 * @date 2025/3/7 15:38
 */
abstract class BaseLoadAdapter<T : Any, VH : RecyclerView.ViewHolder>(
    diffCallback: DiffUtil.ItemCallback<T>
) : PagingDataAdapter<T, VH>(diffCallback) {

    // 数据项点击监听器
    var itemClickListener: ((item: T, position: Int) -> Unit)? = null
    private var recyclerView: RecyclerView? = null
    private var needScrollFirst = false

    init {
        addLoadStateListener {
            if (it.refresh is LoadState.Loading) {
                needScrollFirst = true
            }
        }
        addOnPagesUpdatedListener {
            recyclerView?.post {
                if (needScrollFirst) {
                    scrollFirstWithDelayCheck()
                }
            }
        }
    }

    @SuppressLint("ClickableViewAccessibility")
    private fun scrollFirstWithDelayCheck() {
        needScrollFirst = false
        recyclerView?.scrollToPosition(0)
        recyclerView?.postDelayed(action, 500)
        recyclerView?.setOnTouchListener { _, event ->
            recyclerView?.setOnTouchListener(null)
            recyclerView?.removeCallbacks(action)
            false
        }
    }

    private val action = object : Runnable {
        @SuppressLint("ClickableViewAccessibility")
        override fun run() {
            recyclerView?.setOnTouchListener(null)
            recyclerView?.removeCallbacks(this)
            val layoutManager = recyclerView?.layoutManager
            var firstPosition = -1
            if (layoutManager is GridLayoutManager) {
                firstPosition = layoutManager.findFirstCompletelyVisibleItemPosition()
            } else if (layoutManager is LinearLayoutManager) {
                firstPosition = layoutManager.findFirstCompletelyVisibleItemPosition()
            }
            if (firstPosition > 0) {
                recyclerView?.scrollToPosition(0)
            }
        }
    }

    override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
        super.onAttachedToRecyclerView(recyclerView)
        this.recyclerView = recyclerView
    }


    // 构建带有加载状态的适配器
    private fun buildWithLoadStatus(setLookup: Boolean = true): ConcatAdapter {
        val footerAdapter = LoadingFooterAdapter(setLookup)
        addLoadStateListener { loadStates ->
            footerAdapter.loadState = loadStates.append
        }
        return ConcatAdapter(
            ConcatAdapter.Config.Builder().setIsolateViewTypes(false).build(),
            this,
            footerAdapter
        )
    }

    // 公开的构建方法
    fun buildAdapter(setLookup: Boolean = true) = buildWithLoadStatus(setLookup)

    // 加载底部适配器
    inner class LoadingFooterAdapter(private val setLookup: Boolean = true) :
        LoadStateAdapter<LoadingFooterAdapter.LoadingViewHolder>() {

        private var recyclerViewInstance: RecyclerView? = null

        override fun onBindViewHolder(holder: LoadingViewHolder, loadState: LoadState) {
            holder.binding.loading.isVisible = loadState is LoadState.Loading
            holder.binding.error.isVisible = loadState is LoadState.Error
            holder.binding.nomore.isVisible = loadState is LoadState.NotLoading && loadState.endOfPaginationReached
            holder.binding.error.clickable {
                retry()
            }
        }

        override fun onCreateViewHolder(parent: ViewGroup, loadState: LoadState): LoadingViewHolder {
            return LoadingViewHolder(parent)
        }

        override fun getStateViewType(loadState: LoadState): Int {
            return LOADING_FOOTER_TYPE
        }

        override fun onViewAttachedToWindow(holder: LoadingViewHolder) {
            super.onViewAttachedToWindow(holder)
            holder.binding.loading.isVisible = loadState is LoadState.Loading
            holder.binding.error.isVisible = loadState is LoadState.Error
            holder.binding.nomore.isVisible = loadState is LoadState.NotLoading && loadState.endOfPaginationReached
            holder.binding.error.clickable { retry() }
        }

        override fun displayLoadStateAsItem(loadState: LoadState): Boolean {
            return loadState is LoadState.Loading || (loadState is LoadState.NotLoading && loadState.endOfPaginationReached)
        }

        override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
            super.onAttachedToRecyclerView(recyclerView)
            this.recyclerViewInstance = recyclerView
            if (!setLookup) return
            val adapter = recyclerView.adapter ?: return
            val layoutManager = recyclerView.layoutManager
            if (layoutManager is GridLayoutManager) {
                val defaultSpanSizeLookup = layoutManager.spanSizeLookup
                layoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
                    override fun getSpanSize(position: Int): Int {
                        val viewType = adapter.getItemViewType(position)
                        return if (viewType == LOADING_FOOTER_TYPE) layoutManager.spanCount else defaultSpanSizeLookup.getSpanSize(
                            position
                        )
                    }
                }
            }
        }

        // 加载视图持有者
        inner class LoadingViewHolder(
            parent: ViewGroup,
            val binding: AdapterLoadingFooterBinding = AdapterLoadingFooterBinding.inflate(
                parent.layoutInflater,
                parent,
                false
            )
        ) : RecyclerView.ViewHolder(binding.root)
    }

    companion object {
        // 加载底部视图类型常量
        const val LOADING_FOOTER_TYPE = 1293213
    }
}